package org.example.erat.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.erat.dto.ClassDTO;
import org.example.erat.entity.ClassEntity;
import org.example.erat.entity.Course;
import org.example.erat.exception.ResourceNotFoundException;
import org.example.erat.repository.ClassRepository;
import org.example.erat.repository.CourseRepository;
import org.example.erat.repository.StudentRepository;
import org.example.erat.service.ClassService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 班级服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ClassServiceImpl implements ClassService {

    private final ClassRepository classRepository;
    private final CourseRepository courseRepository;
    private final StudentRepository studentRepository;

    @Override
    @Transactional
    public ClassDTO createClass(ClassDTO classDTO) {
        log.info("创建班级: {}", classDTO.getName());

        Course course = courseRepository.findById(classDTO.getCourseId())
                .orElseThrow(() -> new ResourceNotFoundException("课程不存在: " + classDTO.getCourseId()));

        ClassEntity classEntity = ClassEntity.builder()
                .name(classDTO.getName())
                .course(course)
                .build();

        ClassEntity savedClass = classRepository.save(classEntity);
        return convertToDTO(savedClass);
    }

    @Override
    @Transactional
    public ClassDTO updateClass(Long id, ClassDTO classDTO) {
        log.info("更新班级: {}", id);

        ClassEntity classEntity = classRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("班级不存在: " + id));

        Course course = courseRepository.findById(classDTO.getCourseId())
                .orElseThrow(() -> new ResourceNotFoundException("课程不存在: " + classDTO.getCourseId()));

        classEntity.setName(classDTO.getName());
        classEntity.setCourse(course);

        ClassEntity updatedClass = classRepository.save(classEntity);
        return convertToDTO(updatedClass);
    }

    @Override
    @Transactional
    public void deleteClass(Long id) {
        log.info("删除班级: {}", id);

        ClassEntity classEntity = classRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("班级不存在: " + id));

        classRepository.delete(classEntity);
    }

    @Override
    public ClassDTO getClass(Long id) {
        log.info("获取班级: {}", id);

        ClassEntity classEntity = classRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("班级不存在: " + id));

        return convertToDTO(classEntity);
    }

    @Override
    public List<ClassDTO> getAllClasses() {
        log.info("获取所有班级");

        List<ClassEntity> classes = classRepository.findAll();
        return classes.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ClassDTO> getClassesByCourse(Long courseId) {
        log.info("获取课程的班级列表: {}", courseId);

        Course course = courseRepository.findById(courseId)
                .orElseThrow(() -> new ResourceNotFoundException("课程不存在: " + courseId));

        List<ClassEntity> classes = classRepository.findByCourse(course);
        return classes.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 将班级实体转换为DTO
     * @param classEntity 班级实体
     * @return 班级DTO
     */
    private ClassDTO convertToDTO(ClassEntity classEntity) {
        int studentCount = studentRepository.findByClassEntity(classEntity).size();

        return ClassDTO.builder()
                .id(classEntity.getId())
                .name(classEntity.getName())
                .courseId(classEntity.getCourse().getId())
                .courseName(classEntity.getCourse().getName())
                .studentCount(studentCount)
                .build();
    }
}
